2024.4.15 インデックス計算
修正するべし
指数加重平均のところに間違いあり
evmの計算を取り除く。Index=の式でOK => 修正済み
Lambdaの設定方法が不適切
=> 全然機能しなかった 0.9999になる。
=> 手動で設定
window期間を決める方法が不適切
目的は、取引が少ないエリアのwindow期間を伸ばし、多いエリアを短くしたいだけ。
直近の取引量の正規化で決めていた❌
そのエリアが30日間に平均何回取引があるかを基準にする
=> サンプル数によって新しいエリアは不利になるのでは
=> エリアの取引が初めて起きた日~最新の取引日の期間にする?
? 全体から相対的に決めるべきではない?1日に1回取引があるエリアなら十分と言える?
ウィンドウは7日~30日 rollingした後何取引分のデータか
手動で基準設定
table: window
window 最低取引数 / 月 1日あたり
30 20 0.666
29 24 0.827
28 28 1
27 32 1.185
26 36 1.384
25 40 1.6
24 44 1.83
23 48 2.08
22 52 2.363
21 56 2.66
20 60 3
19 64 3.368
18 68 3.777
17 72 4.235
16 76 4.75
15 80 5.333
14 84 6
13 88 6.769
12 92 7.666
11 96 8.727
10 100 10
9 104 11.555
8 108 13.5
7 112 16
code: python
import pandas as pd
from datetime import timedelta
import statsmodels.api as sm
from sklearn.linear_model import LinearRegression
from sklearn.feature_selection import SelectKBest, f_regression
from sklearn.feature_selection import RFE
import numpy as np
import matplotlib.pyplot as plt
import datetime
pd.set_option('display.max_columns', None)
データ整える
code: python
df_sale = pd.read_csv('Transactions.csv')
import warnings
warnings.filterwarnings('ignore')
df_sale = df_sale'instance_date', 'area_name_en', 'building_name_en', 'master_project_en', "meter_sale_price"
df_sale = df_sale.rename(columns={'instance_date': 'date'})
df_sale = df_sale.rename(columns={'area_name_en': 'area'})
df_sale = df_sale.rename(columns={'building_name_en': 'building'})
df_sale = df_sale.rename(columns={'master_project_en': 'project'})
df_sale = df_sale.rename(columns={'instance_date': 'date'})
df_sale = df_sale.rename(columns={'area_name_en': 'area'})
df_sale = df_sale.rename(columns={'building_name_en': 'building'})
df_sale = df_sale.rename(columns={'master_project_en': 'project'})
全体のエリアごとの変数を求める
code: python
# 過去90日前の日付を計算
end_date = dateti
me.datetime(2022,12,1)
start_date = end_date - datetime.timedelta(days=90)
# 過去90日間のデータをフィルタリング
# 上記の期間におけるエリアごとに取引量を集計
transaction_count = filtered_df.groupby('area').size()
max_window = 30
min_window = 7
# エリアごとの取引量を正規化(0から1の範囲にする)
normalized_count = (transaction_count - transaction_count.min()) / (transaction_count.max() - transaction_count.min())
# エリアごとのウィンドウ期間を決定する
dynamic_window = max_window - (max_window - min_window) * normalized_count
dynamic_window = np.round(dynamic_window).astype(int)
# dynamic_windowの値をカラムにしてデータフレームを作成
df_window = pd.DataFrame({'dynamic_window': dynamic_window})
# エリアごとの減衰係数 lamda を取引量の正規化の値で定義する
# ここ直す
lambdas = normalized_count
df_lambda = pd.DataFrame({'lambda': lambdas})
エリアごとのインデックスを求める
code: python
select_area = 'Marsa Dubai'
df_spe_area = df_sale[df_sale'area' == select_area] specified_date = end_date
# 同じ日付のインデックスでグループ化し、meter_sale_priceの中央値を計算
# 中央値を新しいデータフレームに変換
area_df_median = area_df_median.to_frame()
# area_df_medianデータフレームのインデックスをリセット
area_df_median.reset_index(inplace=True)
area_df_median.set_index('date', inplace=True)
area_df_median.index = pd.to_datetime(area_df_median.index)
area_df_median = area_df_median.sort_index()
# 新しいデータフレームのインデックスにおいて、日付を連続するように補完し、空欄の行は直前のデータを参照する。
area_df_median = area_df_median.asfreq('D', method='ffill')
# カラム meter_sale_price を線形補完
# ローリングウィンドウを適用して smoothed_price を計算
# 動的ウィンドウを使って移動中央値を算出完了
減退係数を使って指数加重平均化してから7日間で平滑化
code:python
# 重みを計算
W_ti = 1 / lambda_
W_si = 1 - W_ti
# end_dateの1日前を取得
end_date_minus_one = end_date - datetime.timedelta(days=1)
# end_date以前の最新のデータを取得
# 最終的なインデックスを算出
# 直近7日間でのrolling
rolling_window = 7
求めたIndexをデータフレームに格納
code: python
latest_date = area_df_median.index.max()
latest_row = area_df_median.loc[area_df_median.index == latest_date, 'property_index'] latest_row'date' = latest_date latest_row = latest_row.set_index('date')
if 'new_df' not in locals():
new_df = latest_row
else:
new_df = new_df.sort_index()
データをグラフにする
code: python
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
# 表示する日付の範囲を指定
start_date = '2022-12-01'
end_date = '2023-02-20'
# グラフの大きさを設定
fig, ax = plt.subplots(figsize=(16, 8))
# データをプロット
# グラフのx軸の範囲を設定
ax.set_xlim(pd.to_datetime(start_date), pd.to_datetime(end_date))
# グラフのタイトルとラベルを設定
ax.set_title('Property_index')
ax.set_xlabel('Date')
ax.set_ylabel('Index')
# グラフを表示
plt.show()